// widetools.cpp
//
// Wide (i.e. Unicode related) tools

#include "wideTools.h"

namespace simple{
    //
    // WideTools
    //
    WideTools* WideTools::_sOnly = 0;

    WideTools& WideTools::gOnly ()
    {
        if (!_sOnly)
            _sOnly = new WideTools ();
        return *_sOnly;
    }

    WideTools::WideTools () : _endian (eUnknownEndian)
    {
        // Check our endian-ness
        _endian = checkBOM (bom());
    }


    WideTools::eBOM WideTools::checkBOM (wchar_t value) const
    {
        unsigned char* p = reinterpret_cast<unsigned char*> (&value);
        unsigned bom1      = *p++;
        unsigned char bom2 = *p;
        if (bom1 == 0xff && bom2 == 0xfe)
            return eLittleEndian;
        if (bom1 == 0xfe && bom2 == 0xff)
            return eBigEndian;

        return eUnknownEndian;
    }

    wchar_t WideTools::swap (wchar_t value)
    {
        return (((value >> 8) & 0x00ff) | 
                        ((value << 8) & 0xff00));
    }

    unsigned long WideTools::swap (unsigned long value)
    {
        return (((value >>24) & 0x000000ff) | 
                ((value >> 8) & 0x0000ff00) | 
                ((value << 8) & 0x00ff0000) | 
                ((value <<24) & 0xff000000));
    }


    void WideTools::swap (std::wstring& value)
    {
        wchar_t* p = const_cast<wchar_t*> (value.c_str());
        for (unsigned int i=0; i<value.size(); i++)
            swap (*p++);
    }
}